//获取应用实例  
const app = getApp()  
const bodyFatData = require('./bodyFatData.js')
const AICARE_FLAG = 'ac'           //aicare标志位
const TYPE_WEI = '02'             //体脂/人体秤
const SYNC_USER_ID = 'fa'         //设置用户ID
const SYNC_USER_INFO = 'fb'       //设置用户信息
const SETTINGS = 'cc'             //设置
const AICARE_SERVICE_UUID = '0000FFB0-0000-1000-8000-00805F9B34FB'    //服务扫描UUID
const AICARE_WRITE_CHARACTERISTIC_UUID = '0000FFB1-0000-1000-8000-00805F9B34FB'    //写入UUID
const AICARE_NOTIFY_CHARACTERISTIC_UUID = '0000FFB2-0000-1000-8000-00805F9B34FB'   //广播接收UUID
Page({

  deviceId: null,
  serviceId: null,
  blueAilable: false,       //蓝牙适配器是否可用
  blueDiscovering: false,   //蓝牙适配器是否处于搜索状态
  isLoading:false,
  /**
   * 页面的初始数据
   */
  data: {
    deviceScanningTime:60,
    deviceConnectStatus:false,
    bodyFatData: bodyFatData.bodyFatData,
    bodyFatDataEvaluate: bodyFatData.bodyFatDataEvaluate,
    bodyFatDataArray: bodyFatData.getBodyFatDataArray()
  },
  ab2hex: function (buffer) {
    let hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },
  ab2Array: function (buffer) {
    let hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr;
  },
  syncUserId: function (res){
    let hex_body = SYNC_USER_ID + '010000' + SETTINGS
    let hex = AICARE_FLAG + TYPE_WEI + hex_body + this.getByteSum(hex_body)
    console.log("syncUserId-hex:" + hex)
    let typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    let buffer = typedArray.buffer
    wx.writeBLECharacteristicValue({
      // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
      deviceId: this.deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: AICARE_SERVICE_UUID,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: AICARE_WRITE_CHARACTERISTIC_UUID,
      // 这里的value是ArrayBuffer类型
      value: buffer,
      success: (res) => {
        console.log('syncUserId success', res.errMsg)
        this.syncUserInfo()
      }
    })
  },
  //设置用户身高年龄
  syncUserInfo: function (res){
    console.log("syncUserInfo",bodyFatData.user)
    if (!(bodyFatData.userInfo.height && bodyFatData.userInfo.sex && bodyFatData.userInfo.age)) {
      this.jumpUserPage()
      return false
    }
    let hex_body = SYNC_USER_INFO + '0' + bodyFatData.userInfo.sex.toString(16) + 
      bodyFatData.userInfo.age.toString(16) + bodyFatData.userInfo.height.toString(16) + SETTINGS
    let hex = AICARE_FLAG + TYPE_WEI + hex_body + this.getByteSum(hex_body)
    console.log("syncuser-hex:",hex)
    let typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    let buffer = typedArray.buffer
    console.log(buffer)
    wx.writeBLECharacteristicValue({
      // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
      deviceId: this.deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: AICARE_SERVICE_UUID,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: AICARE_WRITE_CHARACTERISTIC_UUID,
      // 这里的value是ArrayBuffer类型
      value: buffer,
      success: (res) => {
        console.log('syncuser success', res.errMsg)
        this.setData({ deviceConnectStatus:true})
        wx.showModal({
          title: '连接成功',
          content: '您可以上秤测量了！',
          showCancel: false
        })
      }
    })
  },
  //启用低功耗蓝牙设备特征值变化时的 notify 功能
  notifyBLECharacteristicValueChange: function(res){
    // let characteristicId = res.characteristics[0].uuid
    console.log("notifyBLECharacteristicValueChange",res)
    wx.notifyBLECharacteristicValueChange({
      state: true, // 启用 notify 功能
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
      deviceId: this.deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: AICARE_SERVICE_UUID,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: AICARE_NOTIFY_CHARACTERISTIC_UUID,
      state: true,
      success: (res) => {
        console.log('notifyBLECharacteristicValueChange success', res.errMsg)
        wx.onBLECharacteristicValueChange(this.onBLECharacteristicValueChange)
      }
    })
  },
  //监听低功耗蓝牙设备的特征值变化
  onBLECharacteristicValueChange: function (res){
    console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
    let b = this.ab2Array(res.value)
    console.log("onBLECharacteristicValueChange",b)
    //更新体脂数据
    this.updateBodyFatData(b)
  },
  //获取蓝牙设备某个服务中的所有 characteristic（特征值）
  getBLEDeviceCharacteristics: function (res) {
    wx.getBLEDeviceCharacteristics({
      deviceId: this.deviceId,
      serviceId: AICARE_SERVICE_UUID,
      success: (res) => {
        console.log('device getBLEDeviceCharacteristics:', res.characteristics)
        this.notifyBLECharacteristicValueChange(res)
        this.syncUserId(res)
      }
    })
  },
  //获取蓝牙设备所有 service
  getBLEDeviceServicesSuccess: function (res){
    console.log('device services:', res.services)
    this.serviceId = res.services[1].uuid
    this.getBLEDeviceCharacteristics(res)
  },
  //连接低功耗蓝牙设备成功
  createBLEConnectionSuccess: function (res) {
    console.log('连接低功耗蓝牙设备成功')
    wx.getBLEDeviceServices({
      deviceId: this.deviceId,
      success: this.getBLEDeviceServicesSuccess
    })
  },
  //监听寻找到新设备
  listenBluetoothDeviceFound: function (res) {
    //已经找到设备停止搜索
    wx.stopBluetoothDevicesDiscovery()
    if (!this.deviceId){
      this.deviceId = res.devices[0].deviceId
      console.log('找到设备', this.deviceId);
      //连接低功耗蓝牙设备
      wx.createBLEConnection({
        deviceId: this.deviceId,
        success: this.createBLEConnectionSuccess
      })
    }
  },
  //开始搜寻附近的蓝牙外围设备成功
  startBluetoothDevicesDiscoverySuccess: function (res){
    console.log("开始搜寻附近的蓝牙外围设备")
    wx.onBluetoothDeviceFound(this.listenBluetoothDeviceFound)
    
  },
  listenBluetoothAdapterStateChange: function (res) {

  },
  //开启蓝牙适配器成功
  openBluetoothAdapterSuccess: function(){
    if (!this.blueDiscovering){
      this.blueDiscovering = true
      //开始搜寻附近的蓝牙外围设备
      wx.startBluetoothDevicesDiscovery({
        services: [AICARE_SERVICE_UUID],
        success: this.startBluetoothDevicesDiscoverySuccess
      })
    }
    //监听蓝牙适配器状态变化事件
    wx.onBluetoothAdapterStateChange(this.listenBluetoothAdapterStateChange)
  },
  //开启蓝牙适配器失败
  openBluetoothAdapterFail: function (res){
    wx.showModal({
      title: '蓝牙连接失败',
      content: '请检测蓝牙是否开启！',
    })
  },
  //
  jumpUserPage:function(){
    wx.showModal({
      title: '完善个人信息',
      content: '请去个人中心设置用户基本信息！',
      showCancel: false,
      confirmText: '去设置',
      success: function () {
        console.log("去用户中心")
        wx.switchTab({
          url: '/pages/user/index',
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    bodyFatData.setUserInfo(wx.getStorageSync('user'))
    wx.openBluetoothAdapter({
      success: this.openBluetoothAdapterSuccess,
      fail: this.openBluetoothAdapterFail
    })
    app.userInfoReadyCallback = res => {
      console.log("userInfoReadyCallback", app.globalData.user)
      bodyFatData.setUserInfo(app.globalData.user);
    }
    this.changeDeviceScanningTime()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    if (this.deviceId){
      let userInfo = wx.getStorageSync('user')
      console.log("onShow",userInfo)
      bodyFatData.setUserInfo(userInfo)
      this.syncUserId()
    }
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    // setTimeout(() => { this.setData({ deviceConnectStatus: false })},1000)
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    wx.stopBluetoothDevicesDiscovery({
      success: function (res) {
        console.log('stopBluetoothDevicesDiscovery', res)
      }
    })
    wx.closeBluetoothAdapter({
      success: function (res) {
        console.log('closeBluetoothAdapter', res)
      }
    })
    wx.closeBLEConnection({
      deviceId: this.deviceId,
      success: function (res) {
        console.log('closeBLEConnection', res)
      }
    })
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  changeDeviceScanningTime: function () {
    
    this.setData({
      deviceScanningTime: this.data.deviceScanningTime-1
    })
    if (this.data.deviceScanningTime > 0 && !this.data.deviceConnectStatus){
      setTimeout(this.changeDeviceScanningTime, 1000)
    }
  },
  //解析提取数据
  parseWeightData: function(b){
    return parseInt(b[2] + b[3], 16) / 10;
  },
  //解析提取数据
  parseData: function (b) {
    return parseInt(b[4] + b[5], 16) / 10;
  },
  updateBodyFatData: function(b){
    switch (b[6]){
      case 'ce':    //设置变化体重
        bodyFatData.bodyFatData.weight = this.parseWeightData(b);   
        break; 
      case 'ca':
        bodyFatData.bodyFatData.weight = this.parseWeightData(b); 
        break;
      case 'cb':
        if(b[2] == 'fe'){
          switch (b[3]) {
            case '00':      //体重
              bodyFatData.bodyFatData.weight = this.parseData(b);
              // 标准体重
              let standard_weight = parseFloat(((bodyFatData.userInfo.height * bodyFatData.userInfo.height * 22) / 10000).toFixed(1))
              bodyFatData.bodyFatData.standard_weight = standard_weight
              // 体重控制量
              bodyFatData.bodyFatData.weight_control = parseFloat((Math.abs(standard_weight - bodyFatData.bodyFatData.weight)).toFixed(1))
            case '01':      //BMI
              bodyFatData.bodyFatData.bmi = this.parseData(b);
              bodyFatData.setBmi(bodyFatData.bodyFatData.bmi)
              break;
            case '02':      //体脂率
              let fat_rate = this.parseData(b);
              bodyFatData.bodyFatData.fat_rate = fat_rate
              //脂肪量
              let fat_volume = parseFloat((bodyFatData.bodyFatData.weight * (fat_rate / 100)).toFixed(1))
              bodyFatData.bodyFatData.fat_volume = fat_volume
              //去脂体重
              bodyFatData.bodyFatData.except_fat_weight = parseFloat(((bodyFatData.bodyFatData.weight - bodyFatData.bodyFatData.weight * (fat_rate/100))).toFixed(1))
              bodyFatData.setFatRate(fat_rate)
              break;
            case '03':      //皮下脂肪率
              bodyFatData.bodyFatData.subcutaneous_fat = this.parseData(b)
              break;
            case '04':      //内脏脂肪指数
              bodyFatData.bodyFatData.visceral_fat = parseFloat((this.parseData(b) * 10).toFixed(1))
              bodyFatData.setVisceralFat(bodyFatData.bodyFatData.visceral_fat)
              break;
            case '05':      //肌肉率
              let muscle_rate = this.parseData(b);
              bodyFatData.bodyFatData.muscle_rate = muscle_rate
              bodyFatData.bodyFatData.muscle_volume = parseFloat(((bodyFatData.bodyFatData.weight * (muscle_rate/100))).toFixed(1))
              bodyFatData.setMuscleRate(muscle_rate)
              break;
            case '06':      //基础代谢率
              bodyFatData.bodyFatData.basal_metabolism = (this.parseData(b) * 10)
              bodyFatData.setBasalMetabolism( bodyFatData.bodyFatData.basal_metabolism )
              break;
            case '07':      //骨重量
              bodyFatData.bodyFatData.bone_mass = this.parseData(b)
              bodyFatData.setBoneMass(bodyFatData.bodyFatData.bone_mass)
              break;
            case '08':      //水含量
              bodyFatData.bodyFatData.water_content = this.parseData(b);
              bodyFatData.setWaterContent(bodyFatData.bodyFatData.water_content)
              break;
            case '09':      //身体年龄
              bodyFatData.bodyFatData.body_age = this.parseData(b) * 10;
              break;
            case '0a':      //蛋白率
              let protein_rate = this.parseData(b)
              bodyFatData.bodyFatData.protein_rate = protein_rate
              bodyFatData.bodyFatData.protein_content = parseFloat((bodyFatData.bodyFatData.weight * (protein_rate / 100)).toFixed(1))
              bodyFatData.setProteinRate(protein_rate)
              break;
            case 'fc':
            //体脂数据结束发送
              wx.showToast({
                title: '测量完成',
                icon: 'success',
                duration: 2000
              })
              if (!this.isLoading){
                this.isLoading = true
                console.log("sendfat",bodyFatData.bodyFatData)
                wx.request({
                  url: app.globalData.api_domain + 'min-pro/weight-record',
                  method: 'POST',
                  data: {
                    openid: app.globalData.user.openid,
                    ...bodyFatData.bodyFatData
                  },
                  header: {
                    'token': app.globalData.user.token // 默认值
                  },
                  success: (res) => {
                    this.isLoading = false
                  }
                })
              }
              break;
          }
        }
      case 'cc':
        break;
    }
    console.log("bodyFatData.bodyFatData",bodyFatData.bodyFatData)
    console.log("bodyFatData.bodyFatDataEvaluate", bodyFatData.bodyFatDataEvaluate)
    this.setData({ 
      bodyFatData: bodyFatData.bodyFatData,
      bodyFatDataEvaluate: bodyFatData.bodyFatDataEvaluate,
      bodyFatDataArray: bodyFatData.getBodyFatDataArray()
    })
  },

  getByteSum: function (hex){
    let array =hex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    })
    let abd = 0;
    for (let i = 0; i < array.length; i++) {
      abd += array[i];
    }
    abd = abd.toString(16)
    return abd.substr(abd.length - 2, 2);
  }

})